package com.yunshan.system.config;

import com.alibaba.fastjson2.JSON;
import com.yunshan.common.annotation.RepeatSubmit;
import com.yunshan.common.core.domain.AjaxResult;
import com.yunshan.common.utils.ServletUtils;
import com.yunshan.common.utils.StringUtils;
import com.yunshan.system.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

import static com.yunshan.framework.datasource.DynamicDataSourceContextHolder.log;

/**安全拦截器
 * @author admin001
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {

    private ConcurrentHashMap<String, Long> requestMap = new ConcurrentHashMap<>();

    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
            if (annotation != null) {
                int interval = annotation.interval(); // 使用现有的 interval 属性
                String key = ServletUtils.getRequest().getRequestURI(); // 使用请求 URI 作为唯一键

                Long lastTime = requestMap.get(  key);
                if (lastTime != null && (System.currentTimeMillis() - lastTime) < interval) {
                    ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error("请勿频繁操作")));
                    return false;
                }
                requestMap.put(key, System.currentTimeMillis());
            }
        }

        // 1. 检查 Token 是否存在
        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(401,"请先到个人中心完成登录~")));
            return false;
        }

        // 2. 解析 Token
        String jwt = token.substring(7);
        try {
            Claims claims = jwtUtil.parseToken(jwt);
            String userId = (String) claims.get("userId");
            String openid = (String) claims.get("openid");
            String unionId = (String) claims.get("unionId");

            // 3. 验证会话有效性（检查 Redis 黑名单）
            if (isTokenRevoked(jwt)) {
                ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(402,"Token 已失效")));
                return false;
            }

            // 4. 存储用户信息到请求上下文
            request.setAttribute("userId",userId);
            request.setAttribute("openid", openid);
            request.setAttribute("unionId",unionId);
            return true;

        } catch (Exception e) {
            log.error(e.toString());
            ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(402,"Token 无效或已过期")));
            return false;
        }
    }

    private void sendError(HttpServletResponse response, String message) {
        try {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.setContentType("text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean isTokenRevoked(String token) {
        // 检查 Redis 黑名单
        return Boolean.TRUE.equals(redisTemplate.hasKey("jwt:blacklist:" + token));
    }
}
